package xml.validations;

import java.util.ArrayList;
import java.util.List;

import xml.uidElements.entry.AbstractDataItem;
import xml.uidElements.entry.AbstractStructure;
import xml.uidElements.entry.DataEntryElement;
import xml.uidElements.entry.DataItem;
import xml.uidElements.entry.DataItemSet;
import xml.uidElements.entry.Structure;
import xml.uidElements.entry.StructureSet;

public class FinderInputElements {

	// public List<DataEntryElement> findInput(String id, String data) {
	public List<DataEntryElement> findInput(String data) {

		// data = data.replaceAll(" ", "");

		List<DataEntryElement> l = new ArrayList<DataEntryElement>();

		boolean ehSet = false; // NOVO
		int minCardinality = 0; // NOVO
		int maxCardinality = 0; // NOVO

		String s = "";
		for (int i = 0; i < data.length(); i++) {

			char a = data.charAt(i);
			String b = "" + a;

			// System.out.println(b);

			if (b.equals(",")) {

				if (!s.equals("")) {
					AbstractDataItem d;
					if (ehSet) {
						// d = new DataItemSet(id, s, null);
						d = new DataItemSet(s, null);
						((DataItemSet) d).setCardinality(minCardinality,
								maxCardinality);
					} else
						// d = new DataItem(id, s, null);
						d = new DataItem(s, null);

					l.add(d);
				}
				s = "";
				ehSet = false; // NOVO

			} else if (b.equals(":")) {

				AbstractDataItem d;
				if (ehSet) {
					// d = new DataItemSet(id, s, null);
					d = new DataItemSet(s, null);
					((DataItemSet) d).setCardinality(minCardinality,
							maxCardinality);
				} else
					// d = new DataItem(id, s, null);
					d = new DataItem(s, null);

				i = findDomain(d, i, data);
				l.add(d);
				s = "";
				ehSet = false; // NOVO

			} else if (b.equals("(")) {

				AbstractStructure st;
				if (ehSet) {
					// st = new StructureSet(id, s, "");
					st = new StructureSet(s, "");
					((StructureSet) st).setCardinality(minCardinality,
							maxCardinality);
				} else
					// st = new Structure(id, s, "");
					st = new Structure(s, "");

				// i = findData(st, i, id, data);
				i = findData(st, i, data);
				l.add(st);
				s = "";
				ehSet = false; // NOVO

			} else if (b.equals(")")) {

				AbstractDataItem d;
				if (ehSet) {
//					d = new DataItemSet(id, s, null);
					d = new DataItemSet(s, null);
					((DataItemSet) d).setCardinality(minCardinality,
							maxCardinality);
				} else
//					d = new DataItem(id, s, null);
					d = new DataItem(s, null);
				l.add(d);
				s = "";
				ehSet = false; // NOVO

			} else {

				if (b.equals(".")) {
					// vai procurar os conjuntos representados por ...
					String cardinality = "" + data.charAt(i + 1)
							+ data.charAt(i + 2);
					if (cardinality.equals("..")) {
						i = i + 2;
						ehSet = true; // NOVO
						minCardinality = 0; // NOVO
						maxCardinality = -1; // NOVO

						s = "";
						System.out.println("Entrou para ver a cardinalidade");
					}

				}

				else {
					if (Character.isDigit(data.charAt(i))) {

						ehSet = true; // NOVO

						// vai buscar a cardinalidade minima.
						String stringMinValue = "";
						while (Character.isDigit(data.charAt(i))) {
							stringMinValue = stringMinValue + data.charAt(i);
							i++;
						}
						i--;
						Integer minValue = Integer.parseInt(stringMinValue);
						minCardinality = minValue.intValue();

						// vai buscar a cardinalidade maxima. Se nao encontrar
						// ".." , a cardinalidade maxima vai ser a minima tb.
						String conjunto = "" + data.charAt(i + 1)
								+ data.charAt(i + 2);
						if (conjunto.equals("..")
								&& Character.isDigit(data.charAt(i + 3))) {
							i = i + 3;
							String stringMaxValue = "";
							while (Character.isDigit(data.charAt(i))) {
								stringMaxValue = stringMaxValue
										+ data.charAt(i);
								i++;
							}
							i--;
							Integer maxValue = Integer.parseInt(stringMaxValue);
							maxCardinality = maxValue.intValue();

						} else
							maxCardinality = minValue.intValue(); // NOVO

					}

					else {
						s = s + a;
					}
				}
			}
		}

		if (!s.equals("")) {
//			DataItem d = new DataItem(id, s, null);
			DataItem d = new DataItem(s, null);
			l.add(d);
		}

		return l;
	}

//	private int findData(AbstractStructure st, int i, String id, String data) {
	private int findData(AbstractStructure st, int i, String data) {
		String s = "";
		int j;

		boolean ehSetInTheStructure = false; // NOVO
		int min = 0; // NOVO
		int max = 0; // NOVO

		for (j = i + 1; j < data.length(); j++) {
			char a = data.charAt(j);
			String b = "" + a;
			if (b.equals(")")) {
				if (!s.equals("")) {

					AbstractDataItem d;
					if (ehSetInTheStructure) {
//						d = new DataItemSet(id, s, null);
						d = new DataItemSet(s, null);
						((DataItemSet) d).setCardinality(min, max);
					} else
//						d = new DataItem(id, s, null);
						d = new DataItem(s, null);

					st.addDataEntry(d);
					ehSetInTheStructure = false; // NOVO

				}
				return j;

			} else if (b.equals(",")) {
				if (!s.equals("")) {

					AbstractDataItem d;
					if (ehSetInTheStructure) {
//						d = new DataItemSet(id, s, null);
						d = new DataItemSet(s, null);
						((DataItemSet) d).setCardinality(min, max);
					} else
//						d = new DataItem(id, s, null);
						d = new DataItem(s, null);

					st.addDataEntry(d);
					ehSetInTheStructure = false; // NOVO
				}
				s = "";
			} else if (b.equals(":")) {

				AbstractDataItem d;
				if (ehSetInTheStructure) {
//					d = new DataItemSet(id, s, null);
					d = new DataItemSet(s, null);
					((DataItemSet) d).setCardinality(min, max);
				} else
//					d = new DataItem(id, s, null);
					d = new DataItem(s, null);

				j = findDomain(d, j, data);
				st.addDataEntry(d);
				ehSetInTheStructure = false; // NOVO
				s = "";
			} else if (b.equals("(")) {

				AbstractStructure struct;
				if (ehSetInTheStructure) {
//					struct = new StructureSet(id, s, "");
					struct = new StructureSet(s, "");
					((StructureSet) struct).setCardinality(min, max);
				} else
//					struct = new Structure(id, s, "");
					struct = new Structure(s, "");

//				j = findData(struct, j, id, data);
				j = findData(struct, j, data);
				st.addDataEntry(struct);
				ehSetInTheStructure = false; // NOVO
				s = "";

			} else {

				if (b.equals(".")) {
					String cardinality = "" + data.charAt(j + 1)
							+ data.charAt(j + 2);
					if (cardinality.equals("..")) {
						j = j + 2;
						ehSetInTheStructure = true; // NOVO
						min = 0; // NOVO
						max = -1; // NOVO

						s = "";
						System.out
								.println("Entrou para ver a cardinalidade no outro nivel");
					}

				}

				else {

					if (Character.isDigit(data.charAt(j))) {

						ehSetInTheStructure = true; // NOVO

						// vai buscar a cardinalidade minima.
						String stringMinValue = "";
						while (Character.isDigit(data.charAt(j))) {
							stringMinValue = stringMinValue + data.charAt(j);
							j++;
						}
						j--;
						Integer minValue = Integer.parseInt(stringMinValue);
						min = minValue.intValue();

						// vai buscar a cardinalidade maxima. Se nao encontrar
						// ".." , a cardinalidade maxima vai ser a minima tb.
						String conjunto = "" + data.charAt(j + 1)
								+ data.charAt(j + 2);
						if (conjunto.equals("..")
								&& Character.isDigit(data.charAt(j + 3))) {
							j = j + 3;
							String stringMaxValue = "";
							while (Character.isDigit(data.charAt(j))) {
								stringMaxValue = stringMaxValue
										+ data.charAt(j);
								j++;
							}
							j--;
							Integer maxValue = Integer.parseInt(stringMaxValue);
							max = maxValue.intValue();

						} else
							max = minValue.intValue(); // NOVO

					}

					else

						s = s + a;

				}
			}

		}
		if (!s.equals("")) {
//			DataItem d = new DataItem(id, s, null);
			DataItem d = new DataItem(s, null);
			st.addDataEntry(d);
		}
		return j;
	}

	private int findDomain(AbstractDataItem d, int i, String data) {
		String s = "";
		int j;
		for (j = i + 1; j < data.length(); j++) {
			char a = data.charAt(j);
			String b = "" + a;
			if (b.equals(")")) {
				if (!s.equals(""))
					d.setDomain(s);
				return j - 1;
			} else if (b.equals(",")) {
				if (!s.equals(""))
					d.setDomain(s);
				return j;
			}
			s = s + b;

		}

		if (!s.equals("")) {
			d.setDomain(s);
		}

		return j;
	}

}
